home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / s342q07.lha / sysdep3.c < prev    next >
C/C++ Source or Header  |  1995-09-16  |  56KB  |  1,912 lines

  1. /************************************************************************/
  2. /*                              sysdep3.c                               */
  3. /*                                                                      */
  4. /*      This is the repository of most of the system dependent code     */
  5. /*      in Citadel.  We hope, pray, and proselytize, at least.          */
  6. /************************************************************************/
  7. /************************************************************************/
  8. /*                              history                                 */
  9. /*                                                                      */
  10. /* 86Dec14 HAW  Reorganized into areas.                                 */
  11. /* 86Nov25 HAW  Created.                                                */
  12. /************************************************************************/
  13. #define SYSTEM_DEPENDENT
  14. #define TIMER_FUNCTIONS_NEEDED
  15. #include "ctdl.h"
  16. #include "stdarg.h"
  17. #include "string.h"
  18. #include "dos.h"
  19. #include "time.h"
  20. #include "fcntl.h"
  21. #include "minrexx.h"
  22. /************************************************************************/
  23. /*                              Contents                                */
  24. /*                                                                      */
  25. /*              MODEM HANDLING:                                         */
  26. /*      inp()                   modem input with system overtones       */
  27. /*      MIReady()               check MS-DOS interrupt for data         */
  28. /*      modemClose()            closes down modem I/O                   */
  29. /*      outMod()                bottom-level modem output               */
  30. /*      rawModemInit()          initialize modem                        */
  31. /*      ReInitModem()           reinitialize for recalcitrant modems    */
  32. /*              SYSTEM FORMATTING:                                      */
  33. /*      dPrintf()               printf() that writes to disk            */
  34. /*      mPrintf()               writes a line to modem & console        */
  35. /*      mTrPrintf()             special mPrintf for WC transfers        */
  36. /* #    splitF()                debug formatter                         */
  37. /*              TIMERS:                                                 */
  38. /*      chkTimeSince()          check how long since timer initialized  */
  39. /* #    milliTimeSince()        How long in milliseconds have passed    */
  40. /*      pause()                 pauses for N/100 seconds                */
  41. /* #    setTimer()              start a specific timer.                 */
  42. /*      startTimer()            Initialize a general timer              */
  43. /*      timeSince()             how long since general timer init       */
  44. /*      ReadDate()              interprets time and returns it in secs. */
  45. /*              CONSOLE STUFF, continued                                */
  46. /*      ScreenUser()            update fn for givePrompt()              */
  47. /*      ScrNewUser()            status line updates                     */
  48. /*      SpecialMessage()        special status line messages            */
  49. /*              MISCELLANEOUS:                                          */
  50. /* #    diskSpaceLeft()         amount of space left on specified disk  */
  51. /*      getRawDate()            gets date from system                   */
  52. /*      giveSpaceLeft()         give amount of space left on disk sys   */
  53. /* #    initBadList()           read in list of bad filenames           */
  54. /* #    interpret()             interprets a configuration routine      */
  55. /*      receive()               read modem char or time out             */
  56. /*      runPCPdial()            does a PCPursuit dial                   */
  57. /*      safeopen()              opens a file                            */
  58. /*      setRawDate()            set date (system dependent code)        */
  59. /*      systemCommands()        run outside commands in the O.S.        */
  60. /*      systemInit()            system dependent init                   */
  61. /*      systemShutdown()        system dependent shutdown               */
  62. /*      WhatDay()               returns what day it is                  */
  63. /*                                                                      */
  64. /*              # == local for this implementation only                 */
  65. /************************************************************************/
  66. /************************************************************************/
  67. /*      Globals -- there shouldn't be anything here but statics and     */
  68. /*      externs.                                                        */
  69. /************************************************************************/
  70. extern char *R_W_ANY;
  71. extern char *READ_ANY;
  72. extern char *READ_TEXT;
  73. extern char *APPEND_TEXT;
  74. extern char *APPEND_ANY;
  75. extern char *A_C_TEXT;
  76. extern char *WRITE_TEXT;
  77. extern char *W_R_ANY;
  78. extern char *WRITE_ANY;
  79.  
  80. void  Load_Citadel_Messages(void);
  81.  
  82. void  Do_Stack_Check(void);
  83. void jtimer(unsigned long *timeptr);
  84. int CheckMessageReply(struct Message *inmsg);
  85. void Save_Modem(char *,int ,char *);
  86. void Read_Total_Data(void);
  87. long char_in;           /* total characters input  */
  88.  
  89.  
  90. /* Here's the rest of the goo */
  91. SListBase DirBase  =
  92.   {
  93.   NULL, ChkNtoStr, NULL, FreeNtoStr, EatNMapStr
  94.  
  95.   };
  96. SListBase ResList  =
  97.   {
  98.   NULL, ChkStrtoN, NULL, FreeNtoStr, ResIntrp
  99.  
  100.   };
  101. SListBase BellList =
  102.   {
  103.   NULL, ChkTwoNumbers, NULL, free, EatTwoNumbers
  104.  
  105.   };
  106. char *DirFileName = "ctdldir.sys";
  107. char *ResFileName = "results.sys";
  108. char ResultCodesAvailable;
  109. static char AuditDir[100];
  110. extern logBuffer logBuf;         /* Log buffer of a person       */
  111. extern aRoom     roomBuf;
  112. extern MessageBuffer   msgBuf;
  113. extern CONFIG    cfg;            /* Lots an lots of variables    */
  114. extern NetBuffer netBuf;
  115. extern char onConsole;                  /* Who's in control?!?          */
  116. extern char whichIO;                    /* CONSOLE or MODEM             */
  117. extern char anyEcho;
  118. extern char echo;
  119. extern char modStat;
  120. extern char echoChar;
  121. extern char haveCarrier;
  122. extern char justLostCarrier;
  123. extern char outFlag;
  124. extern char *indexTable;
  125. extern char loggedIn;
  126. /************************************************************************/
  127. /* Section 3.1. MODEM HANDLING:                                         */
  128. /*    These functions are responsible for handling modem I/O.           */
  129. /************************************************************************/
  130. extern struct IOStdReq *consoleReadMsg;
  131. extern struct MsgPort *consoleReadPort;
  132. extern struct IOExtSer *mySerReadMsg;
  133. extern struct MsgPort *mySerReadPort;
  134. extern struct IOExtSer *mySerWriteMsg;
  135. extern struct MsgPort *mySerWritePort;
  136. extern struct timerequest *myTimerMsg;
  137. extern struct MsgPort *myTimerPort;
  138. extern unsigned char serletter,conletter;
  139. extern int serqueued,conqueued;
  140. extern long byteRate;
  141. extern int SerialOpen,DoBufferConsole;
  142. char HasPushBack = FALSE;
  143. long PB,FastBuffAllowed = 1;
  144. long BaudTable[] =
  145.   {
  146.   300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600
  147.  
  148.   };
  149. #define MAXSERIALBUFFER (528)   /* set to 1056 before*/
  150. unsigned char SIBuffer[MAXSERIALBUFFER], *SIBufferPtr, *SIBufferEnd;
  151. long SIBuffered = FALSE;
  152. int QueueSerRead ( int where );
  153. struct Message *MyGetMsg ( struct MsgPort *MyMsgPort );
  154. int OpenSerial ( int starting );
  155. int CloseSerial ( int final );
  156. int UnQueueSerRead ( void );
  157. int ConPutChar ( char myChar );
  158. int Jsystem ( char *cmdline );
  159. int openStuff ( void );
  160. void closeStuff ( int oldprobval );
  161. int Amiga_System_Input ( void );
  162. int QueueRead ( struct IOStdReq *request , char *whereto );
  163. /**** Special Debug code****/
  164. /* capture data to ram:debug.modem */
  165. void Save_Modem(buff,size ,who)
  166. char *buff, *who;
  167. int size;
  168.   {
  169.   /*   disable this routine
  170.   FILE *ram;
  171.   if (cfg.BoolFlags.debug)
  172.     {
  173.     ram = fopen("ram:debug.modem","a");
  174.     if( ram == NULL )
  175.       {
  176.       splitF(NULL," Unable to open ram buffer\n");
  177.       }
  178.     else
  179.       {
  180.       fprintf(ram,"\n%s(%d)",who,size);
  181.       fwrite(buff,size,1,ram);
  182.       fclose(ram);
  183.       };
  184.     }
  185.   */
  186.   }
  187. /************************************************************************/
  188. /*      inp() reads data from port.  Should not be called if there is   */
  189. /*      no data present (for good reason).                              */
  190. /************************************************************************/
  191. unsigned char inp()
  192.   {
  193.   unsigned char temp;
  194.   long readsize;
  195.   Do_Stack_Check();
  196.   char_in++;
  197.   if (HasPushBack)
  198.     {
  199.     HasPushBack = FALSE;
  200.     return (unsigned char) PB;
  201.  
  202.     }
  203.   if (SIBuffered)
  204.     {
  205.     temp = *SIBufferPtr++;
  206.     if (SIBufferPtr == SIBufferEnd)
  207.       {
  208.       SIBuffered = FALSE;
  209.       QueueSerRead(11);
  210.  
  211.       }
  212.     return temp;
  213.  
  214.     }
  215.   WaitPort(mySerReadPort);
  216.   MyGetMsg(mySerReadPort);
  217.   if (mySerReadMsg->IOSer.io_Error)
  218.     {
  219.     printf("\n[1]IOError = %ld\n",(long)mySerReadMsg->IOSer.io_Error);
  220.     mySerReadMsg->IOSer.io_Error = 0;
  221.     if( !gotCarrier() )
  222.       {
  223.       haveCarrier      = FALSE;
  224.       justLostCarrier  = TRUE;
  225.       };
  226.     }
  227.   serqueued = FALSE;
  228.   temp = serletter;
  229.   if (FastBuffAllowed)
  230.     {
  231.     mySerReadMsg->IOSer.io_Command = SDCMD_QUERY;
  232.     DoIO((struct IORequest *)mySerReadMsg);
  233.  
  234.     }
  235.   if (FastBuffAllowed && mySerReadMsg->IOSer.io_Actual)
  236.     {
  237.     readsize = (mySerReadMsg->IOSer.io_Actual > MAXSERIALBUFFER) ? MAXSERIALBUFFER : mySerReadMsg->IOSer.io_Actual;
  238.     mySerReadMsg->IOSer.io_Command = CMD_READ;
  239.     mySerReadMsg->IOSer.io_Data = (APTR)SIBuffer;
  240.     mySerReadMsg->IOSer.io_Length = readsize;
  241.     DoIO((struct IORequest *)mySerReadMsg);
  242.     if (mySerReadMsg->IOSer.io_Error)
  243.       {
  244.       printf("\n[2]IOError = %ld\n",(long)mySerReadMsg->IOSer.io_Error);
  245.       mySerReadMsg->IOSer.io_Error = 0;
  246.       if( !gotCarrier() )
  247.         {
  248.         haveCarrier      = FALSE;
  249.         justLostCarrier  = TRUE;
  250.         return '\0';
  251.         };
  252.       }
  253.     if (mySerReadMsg->IOSer.io_Actual)
  254.       {
  255.       char_in += mySerReadMsg->IOSer.io_Actual;
  256.       SIBufferPtr = SIBuffer;
  257.       SIBufferEnd = SIBuffer + mySerReadMsg->IOSer.io_Actual;
  258.       SIBuffered = TRUE;
  259.       if (cfg.BoolFlags.debug)Save_Modem(SIBufferEnd,mySerReadMsg->IOSer.io_Actual," In:");
  260.  
  261.       }
  262.     else
  263.       {
  264.       QueueSerRead(22);
  265.  
  266.       }
  267.  
  268.     }
  269.   else
  270.     {
  271.     QueueSerRead(2);
  272.  
  273.     }
  274.   return temp;
  275.  
  276.   }
  277. /************************************************************************/
  278. /*      ModemPushBack()  Pushes a character back to modem               */
  279. /************************************************************************/
  280. void ModemPushBack(int c)
  281.   {
  282.   Do_Stack_Check();
  283.   PB = c;
  284.   HasPushBack = TRUE;
  285.  
  286.   }
  287. /************************************************************************/
  288. /*      MIReady() Ostensibly checks to see if input from modem ready    */
  289. /************************************************************************/
  290. int MIReady()
  291.   {
  292.   Do_Stack_Check();
  293.   if (HasPushBack) return(TRUE);
  294.   if (SIBuffered) return(TRUE);
  295.   if (!SerialOpen || !serqueued)
  296.     {
  297.     return(FALSE);
  298.     }
  299.   if (CheckMessageReply((struct Message *)mySerReadMsg))
  300.   return(TRUE);
  301.   return FALSE;
  302.  
  303.   }
  304. /************************************************************************/
  305. /*      gotCarrier() carrier?                                           */
  306. /************************************************************************/
  307. int gotCarrier()
  308.   {
  309.   extern struct IOExtSer *mySerStatusMsg;
  310.   extern char internalserial;
  311.   Do_Stack_Check();
  312.   if (!SerialOpen) return FALSE;
  313.   if (internalserial)
  314.     {
  315.     if ((*((BYTE *) 0xbfd000)) & 0x20) return(FALSE);
  316.  
  317.     }
  318.   else
  319.     {
  320.     mySerStatusMsg->IOSer.io_Command = SDCMD_QUERY;
  321.     DoIO((struct IORequest *)mySerStatusMsg);
  322.     if (mySerStatusMsg->io_Status & 0x20) return(FALSE);
  323.  
  324.     }
  325.   return TRUE;
  326.  
  327.   }
  328. /************************************************************************/
  329. /*      changeBauds() change baud rates                                 */
  330. /************************************************************************/
  331. int changeBauds(MenuId id)
  332.   {
  333.   Do_Stack_Check();
  334.   CitadelBaudRate((long) SysopGetNumber(id,"BAUDST", 0l, 8l),"changeBauds");
  335.   return(0);
  336.  
  337.   }
  338. /************************************************************************/
  339. /*      modemClose() Responsible for shutting down I/O                  */
  340. /*      For IBMs, interrupts must be disabled; dropping of DTR is       */
  341. /*      impossible otherwise, for some reason unknown to me.    HAW     */
  342. /*      88Dec16: modified to drop carrier only if need be.  HAW         */
  343. /************************************************************************/
  344. void ModemShutdown(char KillCarr)
  345.   {
  346.   Do_Stack_Check();
  347.   if (KillCarr)
  348.     {
  349.     DisableModem(FALSE);
  350.     pause(50);
  351.  
  352.     }
  353.  
  354.   }
  355. /************************************************************************/
  356. /*      ModemOpen() open the modem for the first time                   */
  357. /************************************************************************/
  358. void ModemOpen(char DoorReturn)
  359.   {
  360.   unsigned char *ptr;
  361.   Do_Stack_Check();
  362.   OpenSerial(TRUE);
  363.   ptr = cfg.DepData.ModemSetup;
  364.   if (!DoorReturn)
  365.     {
  366.     CitadelBaudRate(cfg.sysBaud,"ModemOpen");
  367.     if (*ptr)
  368.       {
  369.       pause(20);
  370.       do
  371.         {
  372.         outMod(*ptr);
  373.         if (*ptr == '\r') pause(10);
  374.         ++ptr;
  375.  
  376.         }
  377.       while (*ptr);
  378.       pause(20);
  379.  
  380.       }
  381.     QueueSerRead(3);
  382.  
  383.     }
  384.  
  385.   }
  386. /************************************************************************/
  387. /*      HangUp()  hang up the modem                                     */
  388. /************************************************************************/
  389. void HangUp(char FromNet)
  390.   {
  391.   Do_Stack_Check();
  392.   if (!FromNet && cfg.DepData.LockPort >= 0) pause(100);
  393.   DisableModem(FromNet);
  394.   EnableModem(FromNet);
  395.  
  396.   }
  397. void Reinitialize()
  398.   {
  399.   ReInitModem();
  400.  
  401.   }
  402. /************************************************************************/
  403. /*      ReInitModem() reinitialize modem at a high speed.               */
  404. /************************************************************************/
  405. void ReInitModem()
  406.   {
  407.   int hadserial;
  408.   Do_Stack_Check();
  409.   if (strLen(cfg.DepData.HiSpeedInit) != 0 && !gotCarrier())
  410.     {
  411.     hadserial = TRUE;
  412.     if (!SerialOpen)
  413.       {
  414.       hadserial = FALSE;
  415.       OpenSerial(TRUE);
  416.       }
  417.     CitadelBaudRate(cfg.sysBaud,"ReInitModem");
  418.     moPuts(cfg.DepData.HiSpeedInit);
  419.     moPuts("\r");
  420.     pause(100);
  421.     if (!hadserial) CloseSerial(FALSE);
  422.  
  423.     }
  424.  
  425.   }
  426.  
  427. /************************************************************************/
  428. /*      CitadelBaudRate() set the baud rate.                            */
  429. /************************************************************************/
  430.  
  431. long Get_CPS(long, char *);
  432.  
  433. void CitadelBaudRate(long baudcode,char *caller)
  434.   {
  435.   long currentrate;
  436.   long realRate;
  437.   extern UBYTE OpenSerFlags;
  438.   Do_Stack_Check();
  439.   if (cfg.BoolFlags.debug)
  440.     {
  441.     splitF(NULL,"CitadelBaudRate(%ld,%s)\n",baudcode,caller);
  442.     };
  443.   currentrate = ( cfg.DepData.LockPort >= 0 ) ? cfg.DepData.LockPort: baudcode;
  444.   byteRate = Get_CPS(baudcode,caller);       /* set the user character per second */
  445.   realRate = Get_CPS(currentrate,caller)*10; /* set the serial port baud rate */
  446.   if (SerialOpen)
  447.     {
  448.     UnQueueSerRead();
  449.     mySerReadMsg->io_Baud     = mySerStatusMsg->io_Baud     = mySerWriteMsg->io_Baud     = realRate;
  450.     mySerReadMsg->io_SerFlags = mySerStatusMsg->io_SerFlags = mySerWriteMsg->io_SerFlags = OpenSerFlags;
  451.     mySerWriteMsg->IOSer.io_Command = SDCMD_SETPARAMS;
  452.     DoIO((struct IORequest *)mySerWriteMsg);
  453.     QueueSerRead(4);
  454.     };
  455.   }
  456. long Get_CPS(long crate, char *who)
  457.   {
  458.   long cpsrate;
  459.   crate &= 0xffff; /* strip sign if too large */
  460.   switch (crate)
  461.     {
  462.     case     0:
  463.     case    30:
  464.     case   300: cpsrate = 30;break;
  465.     case     1:
  466.     case   120:
  467.     case  1200: cpsrate = 120;break;
  468.     case     2:
  469.     case   240:
  470.     case  2400: cpsrate = 240;break;
  471.     case     3:
  472.     case   480:
  473.     case  4800: cpsrate = 480;break;
  474.     case     4:
  475.     case   960:
  476.     case  9600: cpsrate = 960;break;
  477.     case     5:
  478.     case  1440:
  479.     case 14400: cpsrate = 1440;break;
  480.     case     6:
  481.     case  1920:
  482.     case 19200: cpsrate = 1920;break;
  483.     case     7:
  484.     case  3840:
  485.     case 38400: cpsrate = 3840;break;
  486.     case     8:
  487.     case  5760:
  488.     case 57600: cpsrate = 5760;break;
  489.     default:
  490.       splitF(NULL,"Invalid Baud Code:%ld from %s\n",crate,who);
  491.       if( crate == 7200 || crate == 730 )
  492.         {
  493.         cpsrate = 720;
  494.         }
  495.       else if( crate == 12000 )
  496.         {
  497.         cpsrate = 1200;
  498.         }
  499.       else cpsrate = 240;
  500.     };
  501.   return cpsrate;
  502.   }
  503. static int PortVal;
  504. void DisableModem(char FromNet)
  505.   {
  506.   extern char internalserial;
  507.   unsigned char  *ptr = (unsigned char *)0x0BFD000;
  508.   Do_Stack_Check();
  509.   if( internalserial )
  510.     {
  511.     *ptr &= 0x7f;           /* turn off DTR */
  512.     }
  513.   else  CloseSerial(FALSE);
  514.   pause(150);
  515.   }
  516. void EnableModem(char FromNet)
  517.   {
  518.   extern char internalserial;
  519.   unsigned char  *ptr = (unsigned char *)0x0BFD000;
  520.   Do_Stack_Check();
  521.   if( internalserial )
  522.     {
  523.     *ptr |= 0x80;           /*turn on  DTR */
  524.     }
  525.   else    OpenSerial(FALSE);
  526.   if( FromNet )Reinitialize();  /* if from net session, then reinit */
  527.   }
  528. int RottenDial(char *callout_string)
  529.   {
  530.   Do_Stack_Check();
  531.   return(FALSE);
  532.  
  533.   }
  534. /************************************************************************/
  535. /* Section 3.7. SYSTEM FORMATTING:                                      */
  536. /*    These functions take care of formatting to strange places not     */
  537. /* handled by normal C library functions.                               */
  538. /*   dPrintf() print to disk, using putMsgChar().                       */
  539. /*   mPrintf() print out the modem port via a mFormat() call.           */
  540. /*   splitF() debug function, prints to both screen and disk.           */
  541. /************************************************************************/
  542. char bigbuffer[MAXTEXT];
  543. /************************************************************************/
  544. /*      sprintf() write from format+args to supplied string             */
  545. /************************************************************************/
  546. /*int sprintf(char *garp, const char *format, ...)
  547.   {
  548.   va_list argptr;
  549.   va_start(argptr, format);
  550.   vsprintf(garp, format, argptr);
  551.   va_end(argptr);
  552.   return (int)strlen(garp);
  553.   } */
  554. /************************************************************************/
  555. /*      dPrintf() write from format+args to disk, appends a null byte   */
  556. /************************************************************************/
  557. void dPrintf(char *format, ...)
  558.   {
  559.   va_list argptr;
  560.   char *garp;
  561.   va_start(argptr, format);
  562.   vsprintf(bigbuffer, format, argptr);
  563.   va_end(argptr);
  564.   garp = bigbuffer;
  565.   while(*garp)
  566.     {
  567.     putMsgChar(*garp);
  568.     ++garp;
  569.  
  570.     }
  571.   putMsgChar(0);
  572.  
  573.   }
  574. /************************************************************************/
  575. /*      mPrintf() formats format+args to modem and console              */
  576. /************************************************************************/
  577. int mPrintf(char *format, ...)
  578.   {
  579.   va_list argptr;
  580.   va_start(argptr, format);
  581.   vsprintf(bigbuffer, format, argptr);
  582.   va_end(argptr);
  583.   mFormat(bigbuffer);
  584.   return(1);
  585.  
  586.   }
  587. /************************************************************************/
  588. /*      printf() formats format+args to console                         */
  589. /************************************************************************/
  590. int printf(const char *format, ...)
  591.   {
  592.   FILE *fd;
  593.   va_list argptr;
  594.   int     i;
  595.   extern  int  iconify_window;  /* if TRUE, ignore the output */
  596.   extern  char ConOpen;
  597.   va_start(argptr, format);
  598.   vsprintf(bigbuffer, format, argptr);
  599.   va_end(argptr);
  600.   if (ConOpen)
  601.     {
  602.     if (DoBufferConsole)
  603.       for (i = 0; bigbuffer[i]; i++) ConPutChar(bigbuffer[i]);
  604.     else
  605.       {
  606.       BufferingOn();
  607.       for (i = 0; bigbuffer[i]; i++) ConPutChar(bigbuffer[i]);
  608.       BufferingOff();
  609.  
  610.       };
  611.     }
  612.   else if( !iconify_window )
  613.     {
  614.     if ((fd = fopen("crash.sys", A_C_TEXT)) != NULL)
  615.       {
  616.       fprintf(fd,bigbuffer);
  617.       fclose(fd);
  618.       pause(10);  /* short pause to save the world if we die */
  619.       };
  620.     };
  621.   return(1);
  622.  
  623.   }
  624. /************************************************************************/
  625. /*      splitF() formats format+args to file and console                */
  626. /************************************************************************/
  627. void splitF(FILE *diskFile, char *format, ...)
  628.   {
  629.   FILE  *fd;
  630.   extern char *A_C_TEXT;
  631.   char CLogFn[80];
  632.   va_list argptr;
  633.   va_start(argptr, format);
  634.   vsprintf(bigbuffer, format, argptr);
  635.   va_end(argptr);
  636.   printf(bigbuffer);
  637.   if (diskFile != NULL)
  638.     {
  639.     fwrite(bigbuffer, strlen(bigbuffer), 1, diskFile);
  640.     fflush(diskFile);
  641.  
  642.     }
  643.   else
  644.     {
  645.     if( cfg.Audit == 0)return;  /* exit if not configured Auditing*/
  646.     makeAuditName(CLogFn, "debug.sys");
  647.     if ((fd = fopen(CLogFn, A_C_TEXT)) != NULL)
  648.       {
  649.       fprintf(fd,bigbuffer);
  650.       fclose(fd);
  651.  
  652.       }
  653.     else
  654.       {
  655.       printf("DEBUG OPEN Failure: filename is %s",CLogFn );
  656.       };
  657.     pause(10);  /* short pause to save the world if we die */
  658.     };
  659.   }
  660. /************************************************************************/
  661. /*      mTrPrintf() formats format+args to a transmission function      */
  662. /************************************************************************/
  663. void mTrPrintf(char *format, ...)
  664.   {
  665.   va_list argptr;
  666.   int i;
  667.   va_start(argptr, format);
  668.   vsprintf(bigbuffer, format, argptr);
  669.   va_end(argptr);
  670.   for (i = 0; bigbuffer[i]; i++) sendITLchar(bigbuffer[i]);
  671.   sendITLchar(0);      /* Send NULL since it did before */
  672.  
  673.   }
  674. int (*ToFileWork)(int s) = putFLChar;
  675. /************************************************************************/
  676. /*      ToFile() sends the data to file pointed at by upfd              */
  677. /************************************************************************/
  678. void ToFile(char *format, ...)
  679.   {
  680.   va_list argptr;
  681.   int i;
  682.   va_start(argptr, format);
  683.   vsprintf(bigbuffer, format, argptr);
  684.   va_end(argptr);
  685.   for (i = 0; bigbuffer[i]; i++) (*ToFileWork)(bigbuffer[i]);
  686.   (*ToFileWork)(0);      /* Send NULL since it did before */
  687.  
  688.   }
  689. /************************************************************************/
  690. /* Section 3.8. TIMERS:                                                 */
  691. /*    Basically, the idea here is that two functions are available to   */
  692. /* the rest of Citadel.  One starts a timer.  The other allows checking */
  693. /* that timer, to see how much time has passed since that timer was     */
  694. /* started.  The remainder of the functions in this section are internal*/
  695. /* to this implementation, mostly for use by receive().                 */
  696. /* 88Jun28: Now multiple timers accessible to Citadel are supported.    */
  697. /************************************************************************/
  698. static struct timePacket localTimers[10];
  699. /************************************************************************/
  700. /*      chkTimeSince() buffer for timing stuff.  A call to startTimer() */
  701. /*      must have preceded calls to this function.                      */
  702. /*      RETURNS: Time in seconds since last call to startTimer().       */
  703. /************************************************************************/
  704. long chkTimeSince(int TimerId)
  705.   {
  706.   return timeSince(&localTimers[TimerId]);
  707.  
  708.   }
  709. /************************************************************************/
  710. /*      milliTimeSince() Calculate how many milliseconds have passed    */
  711. /************************************************************************/
  712. long milliTimeSince(struct timePacket *Slast)
  713.   {
  714.   long retVal;
  715.   unsigned long curclock[2];
  716.   if (cfg.BoolFlags.debug)
  717.     {
  718.     splitF(NULL,"milliTimeSince(%08.8X [ %ld %ld])\n",Slast, Slast->clock[0], Slast->clock[1]);
  719.     };
  720.   jtimer(curclock);
  721.   retVal = (curclock[0] != Slast->clock[0]) ? 100l : 0l;
  722.   retVal += (curclock[1] - Slast->clock[1]) / 10000;
  723.   return retVal;
  724.  
  725.   }
  726. #ifdef MSDOS_PAUSE
  727. /************************************************************************/
  728. /*      pause() busy-waits N/100 seconds                                */
  729. /************************************************************************/
  730. void pause(int i)
  731.   {
  732.   struct timePacket x;
  733.   long              (*fn)(struct timePacket *r), limit;
  734.   fn = (i <= 99) ? milliTimeSince : timeSince;
  735.   limit = (i <= 99) ? (long) i : (long) (i / 100);    /* Kludge */
  736.   setTimer(&x);
  737.   while ((*fn)(&x) <= limit)
  738.   ;
  739.  
  740.   }
  741. #endif
  742. /************************************************************************/
  743. /*      setTimer() get ready for timing something                       */
  744. /************************************************************************/
  745. void setTimer(struct timePacket *Slast)
  746.   {
  747.   jtimer(Slast->clock);
  748.  
  749.   }
  750. /************************************************************************/
  751. /*      startTimer() Initialize a general timer                         */
  752. /************************************************************************/
  753. void startTimer(int TimerId)
  754.   {
  755.   setTimer(&localTimers[TimerId]);
  756.  
  757.   }
  758. /************************************************************************/
  759. /*      timeSince() Calculate how many seconds have passed since "x"    */
  760. /************************************************************************/
  761. long timeSince(struct timePacket *Slast)
  762.   {
  763.   long retVal;
  764.   unsigned long curclock[2];
  765.   jtimer(curclock);
  766.   retVal = curclock[0] - Slast->clock[0];
  767.   return retVal;
  768.  
  769.   }
  770. #define LeapYear(x)     ((x % 4) ? FALSE : ((year % 100) ? TRUE : FALSE))
  771. /************************************************************************/
  772. /*      ReadDate() interprets the string and returns it in seconds      */
  773. /************************************************************************/
  774. int ReadDate(char *date, long *RetTime)
  775.   {
  776.   static char *MonthTab[] =
  777.     {
  778.     "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
  779.     "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"
  780.  
  781.     };
  782.   static char *KeyWords[] =
  783.     {
  784.     "TODAY", "YESTERDAY"
  785.  
  786.     };
  787.   static char DayPMonth[] =
  788.     {
  789.     31,28,31,30,31,30,31,31,30,31,30,31
  790.  
  791.     };
  792.   int rover, found, keyword = -1;
  793.   int   year, month, day, hours, minutes, seconds, milli;
  794.   label mon;
  795.   char *d = date;
  796.   char  darray[6];              /* see format for utpack() */
  797.   Do_Stack_Check();
  798.   if (strLen(date) == 0) return FALSE;
  799.   if (isdigit(date[0]))
  800.     {
  801.     darray[0] = (char) (atoi(date) + 1900 - 1970);
  802.     while (isdigit(*date)) date++;
  803.  
  804.     }
  805.   else
  806.     {
  807.     getRawDate(&year, &month, &day, &hours, &minutes,
  808.     &seconds, &milli);
  809.     year -= 1970;
  810.     darray[0] = (char) year;
  811.     darray[1] = (char) month;
  812.     darray[2] = (char) day;
  813.  
  814.     }
  815.   for (rover = 0; isalpha(*date); date++, rover++)mon[rover] = toUpper(*date);
  816.   mon[rover] = 0;
  817.   if (rover == 0)
  818.     {
  819.     if( isdigit(d[0]) )
  820.       {
  821.       *RetTime = CurAbsolute() - ( atol(d)*86400l);
  822.       return TRUE;
  823.       }
  824.     return ERROR;
  825.     };
  826.   for (found = rover = 0; rover < NumElems(MonthTab); rover++)
  827.   if (strncmp(mon, MonthTab[rover], strLen(mon)) == SAMESTRING)
  828.     {
  829.     found++;
  830.     darray[1] = (char) (rover + 1);
  831.  
  832.     }
  833.   if (found != 1)
  834.     {
  835.     for (keyword = -1, rover = 0; rover < NumElems(KeyWords); rover++)
  836.     if (strncmp(mon, KeyWords[rover], strLen(mon)) == SAMESTRING)
  837.       {
  838.       keyword = rover;
  839.  
  840.       }
  841.     if (keyword == -1)
  842.     return ERROR;
  843.     else
  844.       {
  845.       switch(keyword)
  846.         {
  847.         case 0: /* TODAY */
  848.         break;
  849.         case 1: /* YESTERDAY */
  850.         --darray[2];
  851.         if (!darray[2])
  852.           {
  853.           --darray[1];
  854.           if (!darray[1])
  855.             {
  856.             darray[1] = 12;
  857.             --darray[0];
  858.  
  859.             }
  860.           darray[2] = DayPMonth[darray[1] - 1];
  861.           if (darray[1] == 2 && LeapYear(darray[0]))
  862.           darray[2] = 29;
  863.  
  864.           }
  865.         break;
  866.  
  867.         }
  868.  
  869.       }
  870.  
  871.     }
  872.   if ((keyword == -1) && ((darray[2] = (char) atoi(date)) == 0)) return ERROR;
  873.   darray[3] = 0;
  874.   darray[4] = 0;
  875.   darray[5] = 0;
  876.   *RetTime = utpack(darray);
  877.   return TRUE;
  878.  
  879.   }
  880. /************************************************************************/
  881. /*      AbsToReadable() return a human string representing that date    */
  882. /************************************************************************/
  883. char *AbsToReadable(unsigned long lastdate)
  884.   {
  885.   struct tm   *data;
  886.   char        *m;
  887.   static char buffer[40];
  888.   extern char *monthTab[];
  889.   Do_Stack_Check();
  890.   /* 0l represents never in our scheme */
  891.   if (lastdate == 0l) return "Never";
  892.   data = localtime((time_t const *)&lastdate);
  893.   civTime(&data->tm_hour, &m);
  894.   sPrintf(buffer, "%d%s%02d @ %d:%02d %s",
  895.   data->tm_year, monthTab[data->tm_mon + 1],
  896.   data->tm_mday, data->tm_hour, data->tm_min, m);
  897.   return buffer;
  898.  
  899.   }
  900. /************************************************************************/
  901. /*      CurAbsolute() current time in absolute terms.                   */
  902. /************************************************************************/
  903. long CurAbsolute()
  904.   {
  905.   Do_Stack_Check();
  906.   return time(NULL);
  907.  
  908.   }
  909. /************************************************************************/
  910. /*      getCh() Gets char from console.  We do not use a para. define   */
  911. /*      here because we must have a pointer to function elsewhere, and  */
  912. /*      the way we do it here should save a bit of space.               */
  913. /************************************************************************/
  914. int getCh()
  915.   {
  916.   int temp;
  917.   extern struct IOStdReq *consoleReadMsg;
  918.   Do_Stack_Check();
  919.   WaitPort(consoleReadPort);
  920.   MyGetMsg(consoleReadPort);
  921.   conqueued = FALSE;
  922.   temp = conletter;
  923.   QueueRead(consoleReadMsg, &conletter);
  924.   return temp;
  925.  
  926.   }
  927. /************************************************************************/
  928. /*      KBReady() returns TRUE if a console char is ready               */
  929. /************************************************************************/
  930. char KBReady()
  931.   {
  932.   extern char ConOpen;
  933.   Do_Stack_Check();
  934.   if (!ConOpen || !conqueued) return(FALSE);
  935.   if (CheckMessageReply((struct Message *)consoleReadMsg))
  936.   return TRUE;
  937.   return(FALSE);
  938.  
  939.   }
  940. /************************************************************************/
  941. /*      Section 3.9. MISCELLANEOUS                                      */
  942. /************************************************************************/
  943. int strncmpU(char *first, char *second, int length)
  944.   {
  945.   Do_Stack_Check();
  946.   while ((*first) && (*second) && (length > 0))
  947.     {
  948.     if (toupper(*first) != toupper(*second))
  949.     return((int)(*first - *second));
  950.     ++first;
  951.     ++second;
  952.     --length;
  953.  
  954.     }
  955.   return(0);
  956.  
  957.   }
  958. /************************************************************************/
  959. /*      diskSpaceLeft() Amount of space left on specified disk          */
  960. /************************************************************************/
  961. void diskSpaceLeft(char *drive, long *sectors, long *bytes)
  962.   {
  963.   struct InfoData dfreeblk;
  964.   char *fs, temp[150];
  965.   Do_Stack_Check();
  966.   if (drive != NULL)
  967.     {
  968.     if (strncmpU(drive,"RAM:",4) == SAMESTRING)
  969.       {
  970.       *bytes = AvailMem(0L) - 100000;
  971.       if (*bytes < 0)
  972.       *bytes = 0;
  973.       *sectors = ((*bytes) + 127) / SECTSIZE;
  974.       return;
  975.  
  976.       }
  977.     else
  978.       {
  979.       strcpy(temp, drive);
  980.       fs = strchr(temp,':');
  981.       if (fs != NULL)
  982.       *fs = 0;
  983.       else
  984.         {
  985.         *bytes = 0;
  986.         *sectors = 0;
  987.         return;
  988.  
  989.         }
  990.       getdfs(temp, &dfreeblk);
  991.  
  992.       }
  993.  
  994.     }
  995.   else  getdfs(NULL, &dfreeblk);
  996.   *bytes = (long) ((dfreeblk.id_NumBlocks - dfreeblk.id_NumBlocksUsed) *
  997.   dfreeblk.id_BytesPerBlock);
  998.   *sectors = ((*bytes) + 127) / SECTSIZE;
  999.  
  1000.   }
  1001. /************************************************************************/
  1002. /*      getRawDate() gets raw date from MSDOS                           */
  1003. /************************************************************************/
  1004. void getRawDate(int *year, int *month, int *day, int *hours, int *minutes,
  1005. int *seconds, int *milli)
  1006.   {
  1007.   long t;
  1008.   struct tm *v;
  1009.   Do_Stack_Check();
  1010.   time(&t);
  1011.   v        = localtime(&t);
  1012.   *year    = v->tm_year + 1900;
  1013.   *month   = v->tm_mon + 1;
  1014.   *day     = v->tm_mday;
  1015.   *hours   = v->tm_hour;
  1016.   *minutes = v->tm_min;
  1017.   *seconds = v->tm_sec;
  1018.   *milli   = 0;
  1019.  
  1020.   }
  1021. /************************************************************************/
  1022. /*      giveSpaceLeft() give amount of space left on system.            */
  1023. /************************************************************************/
  1024. void giveSpaceLeft(aRoom *roomData)
  1025.   {
  1026.   long        sectors, bytes;
  1027.   extern char remoteSysop;
  1028.   Do_Stack_Check();
  1029.   if (setSpace(roomData))
  1030.     {
  1031.     diskSpaceLeft(NULL, §ors, &bytes);
  1032.     if (!remoteSysop)
  1033.     printf("\nThere are %s bytes left\n",
  1034.     PrintPretty(bytes, msgBuf.mbtext));
  1035.     else
  1036.     mPrintf("\nThere are %s bytes left\n",
  1037.     PrintPretty(bytes, msgBuf.mbtext));
  1038.  
  1039.     }
  1040.   homeSpace();
  1041.  
  1042.   }
  1043. /************************************************************************/
  1044. /*      receive() gets a modem character, or times out ...              */
  1045. /*      Returns:        char on success else ERROR                      */
  1046. /************************************************************************/
  1047. int receive(int seconds)
  1048.   {
  1049.   unsigned long smask,tmask,got;
  1050.   int tout;
  1051.   Do_Stack_Check();
  1052.   if (!gotCarrier()) return ERROR;
  1053.   if (MIReady()) return (int)inp();
  1054.   tmask = (1L << myTimerPort->mp_SigBit);
  1055.   smask = (1L << mySerReadPort->mp_SigBit);
  1056.   myTimerMsg->tr_node.io_Command = TR_ADDREQUEST;
  1057.   myTimerMsg->tr_time.tv_secs = seconds;
  1058.   myTimerMsg->tr_time.tv_micro = 0;
  1059.   SendIO((struct IORequest *)myTimerMsg);
  1060.   tout = 1;
  1061.   got = Wait(tmask | smask | SIGBREAKF_CTRL_F);
  1062.   if (got & tmask)
  1063.     {
  1064.     WaitPort(myTimerPort);
  1065.     MyGetMsg(myTimerPort);
  1066.     tout = 0;
  1067.  
  1068.     }
  1069.   if (got & smask || got & SIGBREAKF_CTRL_F )
  1070.     {
  1071.     if (tout)
  1072.       {
  1073.       AbortIO((struct IORequest *)myTimerMsg);
  1074.       WaitPort(myTimerPort);
  1075.       MyGetMsg(myTimerPort);
  1076.       }
  1077.  
  1078.     }
  1079.   if (MIReady()) return (int)inp();
  1080.   return ERROR;
  1081.  
  1082.   }
  1083. #ifdef AMIGA_READY
  1084. #ifdef NEED_AVAILABLE
  1085. /************************************************************************/
  1086. /*      setRawDate() set system date                                    */
  1087. /************************************************************************/
  1088. char setRawDate(int year, int month, int day, int hour, int mins)
  1089.   {
  1090.   struct time timeblk;
  1091.   struct date dateblk;
  1092.   Do_Stack_Check();
  1093.   timeblk.ti_min  = mins;
  1094.   timeblk.ti_hour = hour;
  1095.   timeblk.ti_sec  = 0   ;
  1096.   timeblk.ti_hund = 0   ;
  1097.   dateblk.da_year = year;
  1098.   dateblk.da_day  = day ;
  1099.   dateblk.da_mon  = month;
  1100.   setdate(&dateblk);
  1101.   settime(&timeblk);
  1102.   return TRUE;
  1103.  
  1104.   }
  1105. #endif
  1106. /************************************************************************/
  1107. /*      safeopen() Opens a file                                         */
  1108. /************************************************************************/
  1109. FILE *safeopen(char *fn, char *mode)
  1110.   {
  1111.   struct stat buff;
  1112.   Do_Stack_Check();
  1113.   if (stat(fn, &buff) == 0)
  1114.   if (buff.st_mode & S_IFCHR)
  1115.   return NULL;
  1116.   return fopen(fn, mode);
  1117.  
  1118.   }
  1119. #endif
  1120. /************************************************************************/
  1121. /*      specCmpU() special compare for this version's file tags         */
  1122. /************************************************************************/
  1123. int specCmpU(char *f1, char *f2)
  1124.   {
  1125.   Do_Stack_Check();
  1126.   while (toUpper(*f1) == toUpper(*f2)) f1++, f2++;
  1127.   if (*f1 == 0 && *f2 == ' ') return SAMESTRING;
  1128.   if (*f2 == 0) return -1;
  1129.   if (toUpper(*f1) < toUpper(*f2)) return -1;
  1130.   return 1;
  1131.  
  1132.   }
  1133. /************************************************************************/
  1134. /*      systemCommands() Some MS-DOS commands                           */
  1135. /************************************************************************/
  1136. void systemCommands()
  1137.   {
  1138.   FILE *fd;
  1139.   char cx, sbigbuffer[200];
  1140.   long countmeup;
  1141.   Do_Stack_Check();
  1142.   while (onLine())
  1143.     {
  1144.     outFlag = OUTOK;
  1145.     mPrintf("\n System commands: ");
  1146.     cx = iChar();
  1147.     switch (toUpper(cx))
  1148.       {
  1149.       case 'F':
  1150.       FastBuffAllowed = !FastBuffAllowed;
  1151.       mPrintf("astbuffer %sallowed\n ",(FastBuffAllowed) ? "" : "not ");
  1152.       break;
  1153.       case 'B':
  1154.       countmeup = 0;
  1155.       while(MIReady())
  1156.         {
  1157.         ++countmeup;
  1158.         inp();
  1159.  
  1160.         }
  1161.       printf("Flushed out %ld chars\n",countmeup);
  1162.       break;
  1163.       case 'X':
  1164.       mPrintf("\bExit from System Commands menu\n ");
  1165.       return ;
  1166.       case 'D':
  1167.       mPrintf("elete file\n ");
  1168.       getNormStr("EFILEN", sbigbuffer, 199, 0);
  1169.       doCR();
  1170.       mPrintf("File %s.\n ", (unlink(sbigbuffer) == 0) ?
  1171.       "deleted" : "not found");
  1172.       break;
  1173.       case 'O':
  1174.       mPrintf("utside commands\n One moment, please.");
  1175.       writeSysTab();
  1176.       if ((fd = safeopen(LOCKFILE, "w")) != NULL)
  1177.         {
  1178.         fprintf(fd,
  1179.         "This is the Citadel-86 LOCK file, which is here to prevent you from\n"
  1180.         "accidentally bringing up Citadel from within Citadel.  Do not delete\n"
  1181.         "this file unless you are certain that you do not have Citadel up already.\n");
  1182.         fclose(fd);
  1183.  
  1184.         }
  1185.       getString("CMDLIN", sbigbuffer, 198, 0);
  1186.       if (whichIO == CONSOLE || strLen(sbigbuffer) != 0)
  1187.         {
  1188.         Jsystem(sbigbuffer);
  1189.         /*
  1190.         * This is a kludge.  Since this is in a system dependency
  1191.         * file, I'm not going to bother to really explain or feel
  1192.         * guilty.
  1193.         */
  1194.         if (!gotCarrier()) DisableModem(FALSE);
  1195.         homeSpace();
  1196.  
  1197.         }
  1198.       unlink(indexTable);
  1199.       unlink(LOCKFILE);
  1200.       break;
  1201.       case '?':
  1202.       tutorial("sysopt.mnu", TRUE);
  1203.       break;
  1204.       default:
  1205.         Output_Citadel_Message("HLPMNU",NULL,NULL,NULL);
  1206.       break;
  1207.  
  1208.       }
  1209.  
  1210.     }
  1211.  
  1212.   }
  1213. int ProblemValue;
  1214. /************************************************************************/
  1215. /*      systemInit() system dependent initialization                    */
  1216. /************************************************************************/
  1217. int systemInit()
  1218.   {
  1219.   extern char currentdir[150];     /* current working directory */
  1220.   extern char ourHomeSpace[150];   /* current home area */
  1221.   SYS_FILE filename;
  1222.   extern int  __msflag;                 /* use MSDOS wildcards for now */
  1223.   Do_Stack_Check();
  1224.   __msflag = 1;
  1225.  
  1226.   Load_Citadel_Messages();
  1227.  
  1228.   ProblemValue = openStuff();
  1229.   if (ProblemValue < 99) return(TRUE);
  1230.   getcwd(ourHomeSpace, 149);
  1231.   currentdir[0] = '\0';
  1232.   if (cfg.Audit != 0)
  1233.     {
  1234.     /* ugly kludge */
  1235.     chdir(cfg.auditArea.saDirname);
  1236.     getcwd(AuditDir, sizeof AuditDir);
  1237.     chdir(ourHomeSpace);
  1238.  
  1239.     }
  1240.   else strcpy(AuditDir,ourHomeSpace);    /* fix invalid audit area */
  1241.   makeSysName(filename, DirFileName, &cfg.roomArea);
  1242.   MakeList(&DirBase, filename, NULL);
  1243.   makeSysName(filename, ResFileName, &cfg.roomArea);
  1244.   ResultCodesAvailable = MakeList(&ResList, filename, NULL);
  1245.   ArcInit();
  1246.   #ifdef NEEDED
  1247.   ctrlbrk(Control_C);
  1248.   #endif
  1249.   InitExternEditors();
  1250.   InitProtocols();
  1251.   Read_Total_Data();
  1252.   return 0;
  1253.  
  1254.   }
  1255. /************************************************************************/
  1256. /*      ResIntrp() interprets a line from RESULTS.SYS.                  */
  1257. /************************************************************************/
  1258. void *ResIntrp(char *line)
  1259.   {
  1260.   char *mid;
  1261.   int rover;
  1262.   NumToString *temp;
  1263.   static struct
  1264.     {
  1265.     char *ResName;
  1266.     int  ResVal;
  1267.  
  1268.     } translate[] =
  1269.     {
  1270.       { "#RESULT-300",   R_300 },
  1271.       { "#RESULT-1200",  R_1200 },
  1272.       { "#RESULT-2400",  R_2400 },
  1273.       { "#RESULT-4800",  R_4800 },
  1274.       { "#RESULT-9600",  R_9600 },
  1275.       { "#RESULT-14400", R_14400 },
  1276.       { "#RESULT-19200", R_19200 },
  1277.       { "#RESULT-38400", R_38400 },
  1278.       { "#RESULT-57600", R_57600 },
  1279.       { "#RING",        R_RING },
  1280.       { "#DIALTONE",    R_DIAL },
  1281.       { "#NO-DIALTONE", R_NODIAL },
  1282.       { "#OK",          R_AOK },
  1283.       { "#NO-CARRIER",  R_NOCARR },
  1284.       { "#BUSY",        R_BUSY }
  1285.      };
  1286.   Do_Stack_Check();
  1287.   if ((mid = strchr(line, ' ')) != NULL)
  1288.     {
  1289.     *mid = 0;
  1290.     mid++;
  1291.     while ( *mid == ' ' || *mid == '\t')mid++;  /* skip white space */
  1292.     for (rover = 0; rover < NumElems(translate); rover++)
  1293.     if (strCmpU(line, translate[rover].ResName) == SAMESTRING)
  1294.       {
  1295.       temp = (NumToString *) GetDynamic(sizeof *temp);
  1296.       temp->num = translate[rover].ResVal;
  1297.       temp->string = strdup(mid);
  1298.       if (cfg.BoolFlags.debug)
  1299.         {
  1300.         splitF(NULL," Result code: %d String:-%s-\n",temp->num,temp->string);
  1301.         };
  1302.  
  1303.       return temp;
  1304.  
  1305.       }
  1306.     splitF(NULL," Invalid line in RESULT.SYS:%s\n",line);
  1307.     }
  1308.   return NULL;
  1309.  
  1310.   }
  1311. /************************************************************************/
  1312. /*      ResultVal() if the given value is present, return the parameter */
  1313. /*      it matches.                                                     */
  1314. /************************************************************************/
  1315. int ResultVal(char *buf)
  1316.   {
  1317.   UNS_16 *j;
  1318.   Do_Stack_Check();
  1319.   j = (UNS_16 *) SearchList(&ResList, buf);
  1320.   if (j != NULL)
  1321.   return (int)*j;
  1322.   else
  1323.   return ERROR;
  1324.  
  1325.   }
  1326. /************************************************************************/
  1327. /*      systemShutdown() system dependent shutdown code                 */
  1328. /************************************************************************/
  1329. void systemShutdown(int SystemErrorValue)
  1330.   {
  1331.   Do_Stack_Check();
  1332.   closeStuff(ProblemValue);
  1333.  
  1334.   }
  1335. /************************************************************************/
  1336. /*      BeNice() be nice to the nice operating system                   */
  1337. /************************************************************************/
  1338. void BeNice(int x)
  1339.   {
  1340.   int delay;
  1341.   Do_Stack_Check();
  1342.   if( x != NET_PAUSE)Amiga_System_Input();
  1343.   switch(x)
  1344.     {
  1345.     case INUSE_PAUSE: delay =  5;break;
  1346.     case   CHAT_NICE: delay =  2;break;
  1347.     case  IDLE_PAUSE:
  1348.       {
  1349.       delay = 50;
  1350.       SpecialMessage("Status:Idle");
  1351.       break;
  1352.       };
  1353.     case   NET_PAUSE: delay =  1;break;
  1354.     }
  1355.   pause(delay);
  1356.   }
  1357. void StrollIt(void)
  1358.   {
  1359.  
  1360.   }
  1361. /************************************************************************/
  1362. /*      safeopen()                                                      */
  1363. /************************************************************************/
  1364. FILE *safeopen(char *fn, char *mode)
  1365.   {
  1366.   FILE *rtfp;
  1367.  
  1368.   Do_Stack_Check();
  1369.   /*if (cfg.BoolFlags.debug) splitF(NULL,"safeopen(%s,%s)",fn,mode);*/
  1370.   rtfp = fopen(fn, mode);
  1371.   /*if (cfg.BoolFlags.debug && rtfp == NULL)
  1372.      splitF(NULL," result = %08.8X \n",rtfp); */
  1373.   return  rtfp;
  1374.  
  1375.   }
  1376. /************************************************************************/
  1377. /*              totalBytes() how many bytes in this here file?                                  */
  1378. /************************************************************************/
  1379. void totalBytes(long *size, FILE *fd)
  1380.   {
  1381.   long oldpos;                  /* old position of this file */
  1382.   Do_Stack_Check();
  1383.   oldpos = ftell(fd);           /* save old position */
  1384.   fseek(fd,0l,SEEK_END);       /* go to end of file */
  1385.   *size = ftell(fd);            /* get current position */
  1386.   fseek(fd,oldpos,SEEK_SET);    /* back to begining */
  1387.   }
  1388. /************************************************************************/
  1389. /*      WhatDay() Returns what day it is (0=Sunday...)                  */
  1390. /************************************************************************/
  1391. int WhatDay()
  1392.   {
  1393.   long t;
  1394.   char *s;
  1395.   int  rover;
  1396.   char *Days[] =
  1397.     {
  1398.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  1399.  
  1400.     };
  1401.   Do_Stack_Check();
  1402.   time(&t);
  1403.   s = ctime(&t);
  1404.   /* now find out what day it is */
  1405.   for (rover = 0; rover < 7; rover++)
  1406.   if (strncmp(s, Days[rover], 3) == 0)
  1407.     {
  1408.     return rover;
  1409.  
  1410.     }
  1411.  
  1412.   }
  1413. /************************************************************************/
  1414. /*       DialExternal()                                                 */
  1415. /************************************************************************/
  1416. int DialExternal(NetBuffer *netBuf)
  1417.   {
  1418.   Do_Stack_Check();
  1419.   UnQueueSerRead();
  1420.   Jsystem(netBuf->access);
  1421.   homeSpace();
  1422.   QueueSerRead(5);
  1423.   return gotCarrier();
  1424.  
  1425.   }
  1426. void makeAuditName(char *logfn, char *name)
  1427.   {
  1428.   Do_Stack_Check();
  1429.   sPrintf(logfn, "%s%s%s", AuditDir, (AuditDir[strlen(AuditDir)-1] == ':') ? "" : "/", name);
  1430.  
  1431.   }
  1432. void Intel32ToMotorola(UNS_32 *val)
  1433.   {
  1434.   unsigned long temp;
  1435.   Do_Stack_Check();
  1436.   temp = *val;
  1437.   *val = ((ULONG)(temp & 0xff) << 24) + ((ULONG)(temp & 0xff00) << 8) +
  1438.   ((ULONG)(temp & 0xff0000) >> 8) + ((ULONG)(temp &0xff000000) >> 24);
  1439.  
  1440.   }
  1441. void Intel16ToMotorola(UNS_16 *val)
  1442.   {
  1443.   UNS_16 temp;
  1444.   Do_Stack_Check();
  1445.   temp = *val;
  1446.   *val = ((temp & 0xff) << 8) + ((temp & 0xff00) >> 8);
  1447.  
  1448.   }
  1449. int CheckMessageReply(struct Message *inmsg)
  1450.   {
  1451.   struct Message *tempmsg;
  1452.   struct MsgPort *replyport;
  1453.   Do_Stack_Check();
  1454.   replyport = inmsg->mn_ReplyPort;
  1455.   if (!replyport) return ERROR;
  1456.   Disable();
  1457.   tempmsg = (struct Message *)replyport->mp_MsgList.lh_Head;
  1458.   while(tempmsg)
  1459.     {
  1460.     if (tempmsg == inmsg)
  1461.       {
  1462.       Enable();
  1463.       return TRUE;
  1464.  
  1465.       }
  1466.     tempmsg = (struct Message *)tempmsg->mn_Node.ln_Succ;
  1467.  
  1468.     }
  1469.   Enable();
  1470.   return FALSE;
  1471.  
  1472.   }
  1473. void jtimer(unsigned long *timeptr)
  1474.   {
  1475.   Do_Stack_Check();
  1476.   myTimerMsg->tr_node.io_Command = TR_GETSYSTIME;
  1477.   DoIO((struct IORequest *)myTimerMsg);
  1478.   timeptr[0] = myTimerMsg->tr_time.tv_secs;
  1479.   timeptr[1] = myTimerMsg->tr_time.tv_micro;
  1480.   }
  1481.  
  1482. /*
  1483. **  THIS IS THE START OF THE SYSOP MENU HANDLING CODE
  1484. */
  1485. int    GetMenuSelection(MenuId id);
  1486. MenuId CreateIOWindow(short leftedge, short topedge, short width, short height, char *title);
  1487. void   CloseIOWindow(MenuId MenuPtr);
  1488. struct Window *DoOpenWindow(short leftedge, short topedge, short width, short height, char *title);
  1489. int    CreateInteractiveWindowCon(MenuId id);
  1490. int    DeleteInteractiveWindowCon(MenuId id);
  1491. void   IWCWrite(MenuId id, char *str, long len);
  1492. int    IWCRead(MenuId id, char *str, long len);
  1493. void   IWCReadString(MenuId id, char *prompt, char *buf, int lim);
  1494. /*
  1495. **      RegisterSysopMenu() set up for doing special sysop menus
  1496. */
  1497. MenuId RegisterSysopMenu(char *MenuName, char *Opts[], char *MenuTitle)
  1498.   {
  1499.   int i;
  1500.   Do_Stack_Check();
  1501.   mPrintf(MenuTitle);
  1502.   for (i = 0; Opts[i][0] && Opts[i][0] != ' '; i++)
  1503.     {
  1504.     printf("%s",Opts[i]);
  1505.     };
  1506.  
  1507.   RegisterThisMenu(MenuName, Opts);
  1508.   return NO_MENU;
  1509.  
  1510.   }
  1511. /************************************************************************/
  1512. /*      GetSysopMenuChar() gets a selection from the sysop              */
  1513. /************************************************************************/
  1514. int GetSysopMenuChar(MenuId id)
  1515.   {
  1516.   Do_Stack_Check();
  1517.   return GetMenuChar();
  1518.  
  1519.   }
  1520. /*
  1521. /*      NeedSysopInpPrompt()  A kludge for checking for input
  1522. */
  1523. char NeedSysopInpPrompt(void)
  1524.   {
  1525.   Do_Stack_Check();
  1526.   return((char)onConsole);
  1527.  
  1528.   }
  1529. /*
  1530. **      CloseSysopMenu() closes the sysop's menu
  1531. */
  1532. void CloseSysopMenu(MenuId id)
  1533.   {
  1534.   Do_Stack_Check();
  1535.  
  1536.   }
  1537.  
  1538. /*
  1539. /*      SysopMenuPrompt() prompt handling in sysop menu
  1540. */
  1541. void SysopMenuPrompt(MenuId id, char *prompt)
  1542.   {
  1543.   Do_Stack_Check();
  1544.   if (!onConsole || id == NO_MENU)
  1545.   mPrintf(prompt);
  1546.  
  1547.   }
  1548.  
  1549. /*
  1550. **      SysopError() show an error to the sysop
  1551. */
  1552. void SysopError(MenuId id, char *prompt)
  1553.   {
  1554.   Do_Stack_Check();
  1555.   mPrintf(prompt);
  1556.  
  1557.   }
  1558.  
  1559. /*
  1560. **      SysopGetYesNo() get yes/no from sysop
  1561. */
  1562. char SysopGetYesNo(MenuId id, char *info, char *prompt)
  1563.   {
  1564.   Do_Stack_Check();
  1565.   if( info != NULL)Output_Citadel_Message(info, NULL, NULL, NULL);
  1566.   return getYesNo(prompt);
  1567.   }
  1568. /************************************************************************/
  1569. /*      SysopRequestString() gets a string from the sysop.              */
  1570. /************************************************************************/
  1571. void SysopRequestString(MenuId id, char *prompt, char *buf, int size, int flags)
  1572.   {
  1573.   Do_Stack_Check();
  1574.   getNormStr(prompt, buf, size, flags);
  1575.  
  1576.   }
  1577. /************************************************************************/
  1578. /*      SysopInfoReport() report information to sysop                   */
  1579. /************************************************************************/
  1580. void SysopInfoReport(MenuId id, char *info)
  1581.   {
  1582.   Do_Stack_Check();
  1583.   mPrintf(info);
  1584.  
  1585.   }
  1586. /************************************************************************/
  1587. /*      SysopDisplayInfo() Display info to the sysop                    */
  1588. /************************************************************************/
  1589. void SysopDisplayInfo(MenuId id, char *info, char *title)
  1590.   {
  1591.   Do_Stack_Check();
  1592.   mPrintf(title);
  1593.   mPrintf(info);
  1594.  
  1595.   }
  1596. /************************************************************************/
  1597. /*      SysopGetNumber() get a number from sysop                        */
  1598. /************************************************************************/
  1599. long SysopGetNumber(MenuId id, char *prompt, long bottom, long top)
  1600.   {
  1601.   Do_Stack_Check();
  1602.   return getNumber(prompt, bottom, top);
  1603.  
  1604.   }
  1605. /************************************************************************/
  1606. /*      SysopContinual() open a window for some output                  */
  1607. /************************************************************************/
  1608. MenuId SysopContinual(char *title, char *prompt, int MaxWidth, int Depth)
  1609.   {
  1610.   Do_Stack_Check();
  1611. /**
  1612.   print only if not NULL and length greater than zero
  1613. **/
  1614.   if( title  != NULL)if( strlen(title) )mPrintf(title);
  1615.   if( prompt != NULL)if( strlen(prompt))Output_Citadel_Message(prompt,NULL,NULL,NULL);
  1616.   return NO_MENU;
  1617.  
  1618.   }
  1619. /************************************************************************/
  1620. /*      SysopContinualString() get a string from a window               */
  1621. /************************************************************************/
  1622. void SysopContinualString(MenuId id, char *prompt, char *buf, int size, int flags)
  1623.   {
  1624.   Do_Stack_Check();
  1625.   getNormStr(prompt, buf, size, 0);
  1626.  
  1627.   }
  1628. /************************************************************************/
  1629. /*      SysopPrintf() formats format+args to sysop window               */
  1630. /************************************************************************/
  1631. int SysopPrintf(MenuId id, char *format, ...)
  1632.   {
  1633.   va_list argptr;
  1634.   va_start(argptr, format);
  1635.   vsprintf(bigbuffer, format, argptr);
  1636.   va_end(argptr);
  1637.   Do_Stack_Check();
  1638.   mFormat(bigbuffer);
  1639.   return 0;
  1640.  
  1641.   }
  1642. /************************************************************************/
  1643. /*      SysopCloseContinual() closes continaual IO window               */
  1644. /************************************************************************/
  1645. void SysopCloseContinual(MenuId id)
  1646.   {
  1647.   Do_Stack_Check();
  1648.  
  1649.   }
  1650. /*  These are my functions to support all of these above  */
  1651. int GetMenuSelection(MenuId id)
  1652.   {
  1653.   int goodchar;
  1654.   char testchar;
  1655.   Do_Stack_Check();
  1656.   if (id == NO_MENU || !id->MenuCharList || !id->MenuCharList[0])
  1657.   return(0);
  1658.   goodchar = 0;
  1659.   do
  1660.     {
  1661.     IWCRead(id, &testchar, 1);
  1662.     testchar = toUpper(testchar);
  1663.     if (strchr(id->MenuCharList, testchar) && !goodchar)
  1664.       {
  1665.       goodchar = testchar;
  1666.  
  1667.       }
  1668.  
  1669.     }
  1670.   while(!goodchar);
  1671.   return(goodchar);
  1672.  
  1673.   }
  1674. MenuId CreateIOWindow(short leftedge, short topedge, short width, short height, char *title)
  1675.   {
  1676.   MenuId MenuPtr;
  1677.   struct Window *WPtr;
  1678.   Do_Stack_Check();
  1679.   WPtr = DoOpenWindow(leftedge, topedge, width, height, title);
  1680.   if (!WPtr)
  1681.     {
  1682.     return NO_MENU;
  1683.  
  1684.     }
  1685.   MenuPtr = (MenuId)malloc(sizeof(struct MenuData));
  1686.   if (!MenuPtr)
  1687.     {
  1688.     CloseWindow(WPtr);
  1689.     return NO_MENU;
  1690.  
  1691.     }
  1692.   memset(MenuPtr, sizeof(struct MenuData), 0);
  1693.   MenuPtr->MenuWindow = WPtr;
  1694.   MenuPtr->MenuCharList = NULL;
  1695.   if (!CreateInteractiveWindowCon(MenuPtr))
  1696.     {
  1697.     CloseWindow(WPtr);
  1698.     free(MenuPtr);
  1699.     return NO_MENU;
  1700.  
  1701.     }
  1702.   return(MenuPtr);
  1703.  
  1704.   }
  1705. void CloseIOWindow(MenuId MenuPtr)
  1706.   {
  1707.   Do_Stack_Check();
  1708.   if (MenuPtr != NO_MENU)
  1709.     {
  1710.     DeleteInteractiveWindowCon(MenuPtr);
  1711.     if (MenuPtr->MenuWindow) CloseWindow(MenuPtr->MenuWindow);
  1712.     free(MenuPtr);
  1713.  
  1714.     }
  1715.  
  1716.   }
  1717. struct Window *DoOpenWindow(short leftedge, short topedge, short width, short height, char *title)
  1718.   {
  1719.   extern struct RastPort *myScreensRPort;
  1720.   extern struct Screen *myScreen;
  1721.   struct NewWindow *NWPtr;
  1722.   struct Window *WPtr;
  1723.   short tlength;
  1724.   Do_Stack_Check();
  1725.   NWPtr = (struct NewWindow *)malloc(sizeof(struct NewWindow));
  1726.   if (NWPtr)
  1727.     {
  1728.     if (title)
  1729.       {
  1730.       tlength = (strlen(title) + 3) * myScreensRPort->TxWidth;
  1731.       if ((width < tlength) && (topedge + tlength < myScreen->Width))
  1732.       width = tlength;
  1733.  
  1734.       }
  1735.     if ((leftedge < 0) || (topedge < 0) || (width < 0) || (height < 0) ||
  1736.     (leftedge + width > myScreen->Width) ||
  1737.     (topedge + height > myScreen->Height))
  1738.       {
  1739.       return(NULL);
  1740.  
  1741.       }
  1742.     NWPtr->LeftEdge             = leftedge;
  1743.     NWPtr->TopEdge              = topedge;
  1744.     NWPtr->Width                = width;
  1745.     NWPtr->Height               = height;
  1746.     NWPtr->DetailPen    = (UBYTE)-1;
  1747.     NWPtr->BlockPen             = (UBYTE)-1;
  1748.     NWPtr->IDCMPFlags   = NULL;
  1749.     NWPtr->Flags                = SMART_REFRESH | NOCAREREFRESH | ACTIVATE | RMBTRAP | WINDOWDEPTH;
  1750.     NWPtr->FirstGadget  = NULL;
  1751.     NWPtr->CheckMark    = NULL;
  1752.     NWPtr->Title                = title;
  1753.     NWPtr->Screen               = myScreen;
  1754.     NWPtr->BitMap               = NULL;
  1755.     NWPtr->MinWidth             = 0;
  1756.     NWPtr->MinHeight    = 0;
  1757.     NWPtr->MaxWidth             = 32767;
  1758.     NWPtr->MaxHeight    = 32767;
  1759.     NWPtr->Type         = CUSTOMSCREEN;
  1760.     WPtr = OpenWindow(NWPtr);
  1761.     free(NWPtr);
  1762.     return(WPtr);
  1763.  
  1764.     }
  1765.   else
  1766.     {
  1767.     return(NULL);
  1768.  
  1769.     }
  1770.  
  1771.   }
  1772. int CreateInteractiveWindowCon(MenuId id)
  1773.   {
  1774.   int error;
  1775.   Do_Stack_Check();
  1776.   if (id == NO_MENU)return(0);
  1777.   if (!(id->MenuIOPort = CreatePort(0,0))) return(0);
  1778.   if (!(id->MenuIOMsg = (struct IOStdReq *)CreateExtIO(id->MenuIOPort, (LONG)sizeof(struct IOStdReq))))
  1779.     {
  1780.     return(DeleteInteractiveWindowCon(id));
  1781.  
  1782.     }
  1783.   id->MenuIOMsg->io_Data = id->MenuWindow;
  1784.   id->MenuIOMsg->io_Length = sizeof(struct Window);
  1785.   error = OpenDevice("console.device", 0, (struct IORequest *)id->MenuIOMsg, 0);
  1786.   id->DeviceOpen = !error;
  1787.   return(!error);
  1788.  
  1789.   }
  1790. int DeleteInteractiveWindowCon(MenuId id)
  1791.   {
  1792.   Do_Stack_Check();
  1793.   if (id == NO_MENU)  return(0);
  1794.   if (id->DeviceOpen)
  1795.     {
  1796.     CloseDevice((struct IORequest *)id->MenuIOMsg);
  1797.     id->DeviceOpen = 0;
  1798.  
  1799.     }
  1800.   if (id->MenuIOMsg)
  1801.     {
  1802.     DeleteExtIO((struct IORequest *)id->MenuIOMsg);
  1803.     id->MenuIOMsg = 0;
  1804.  
  1805.     }
  1806.   if (id->MenuIOPort)
  1807.     {
  1808.     DeletePort(id->MenuIOPort);
  1809.     id->MenuIOPort = 0;
  1810.  
  1811.     }
  1812.   return(0);
  1813.  
  1814.   }
  1815. void IWCWrite(MenuId id, char *str, long len)
  1816.   {
  1817.   Do_Stack_Check();
  1818.   if (id == NO_MENU || !id->DeviceOpen)  return;
  1819.   id->MenuIOMsg->io_Command = CMD_WRITE;
  1820.   id->MenuIOMsg->io_Data = (APTR)str;
  1821.   id->MenuIOMsg->io_Length = len;
  1822.   id->MenuIOMsg->io_Message.mn_ReplyPort = id->MenuIOPort;
  1823.   DoIO((struct IORequest *)id->MenuIOMsg);
  1824.  
  1825.   }
  1826. int IWCRead(MenuId id, char *str, long len)
  1827.   {
  1828.   Do_Stack_Check();
  1829.   if (id == NO_MENU || !id->DeviceOpen)  return(0);
  1830.   if (!id->MenuIOMsg)
  1831.     {
  1832.     mPrintf("No MenuIOMsg: system error in sysdep3.c\n");
  1833.     return(0);
  1834.     }
  1835.   id->MenuIOMsg->io_Command = CMD_READ;
  1836.   id->MenuIOMsg->io_Data = (APTR)str;
  1837.   id->MenuIOMsg->io_Length = len;
  1838.   id->MenuIOMsg->io_Message.mn_ReplyPort = id->MenuIOPort;
  1839.   DoIO((struct IORequest *)id->MenuIOMsg);
  1840.   return(1);
  1841.  
  1842.   }
  1843. void IWCReadString(MenuId id, char *prompt, char *buf, int lim)
  1844.   {
  1845.   int  i;
  1846.   char c;
  1847.   Do_Stack_Check();
  1848.   if (id == NO_MENU || !id->DeviceOpen)  return;
  1849.   if (strLen(prompt) > 0)
  1850.     {
  1851.     SysopPrintf(id, "Enter %s\n : ", prompt);
  1852.  
  1853.     }
  1854.   i = 0;
  1855.   while (IWCRead(id, &c, 1) && c != NEWLINE && c != 13)
  1856.     {
  1857.     /* handle delete chars: */
  1858.     if (c == BACKSPACE)
  1859.       {
  1860.       if (i > 0)
  1861.         {
  1862.         c = '\b';
  1863.         IWCWrite(id, &c, 1);
  1864.         c = ' ';
  1865.         IWCWrite(id, &c, 1);
  1866.         c = '\b';
  1867.         IWCWrite(id, &c, 1);
  1868.         i--;
  1869.  
  1870.         }
  1871.       else
  1872.         {
  1873.         c = BELL;
  1874.         IWCWrite(id, &c, 1);
  1875.  
  1876.         }
  1877.  
  1878.       }
  1879.     else
  1880.       {
  1881.       if (i >= lim)
  1882.         {
  1883.         c = BELL;
  1884.         IWCWrite(id, &c, 1);
  1885.         c = BACKSPACE;
  1886.         IWCWrite(id, &c, 1);
  1887.         i--;
  1888.  
  1889.         }
  1890.       else
  1891.         {
  1892.         IWCWrite(id, &c, 1);
  1893.         buf[i++] = c;
  1894.  
  1895.         }
  1896.  
  1897.       }
  1898.     if (i >= lim)
  1899.       {
  1900.       c = BELL;
  1901.       IWCWrite(id, &c, 1);
  1902.  
  1903.       }
  1904.  
  1905.     }
  1906.   c = NEWLINE;
  1907.   IWCWrite(id, &c, 1);
  1908.   buf[i]  = '\0';
  1909.   return;
  1910.  
  1911.   }
  1912.